package FrameWork.Event;

import org.apache.log4j.Logger;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.WeakHashMap;

public class TriggerReflectUtil {

    private static Logger logger = Logger.getLogger(TriggerReflectUtil.class);
    //对EventHandler的Order的临时缓存
    private static Map<Class<? extends EventHandler>,Integer> orderCache = new WeakHashMap<>();

    /**
     *
     * @param clazz 事件类型
     * @return 获得其继承的Event<T> T的具体Class
     */
    @SuppressWarnings("unchecked")
    static Class<? extends EventHandler> getEventHandlerType(final Class<? extends Trigger> clazz) {
        Type type = clazz.getGenericSuperclass();
        String typeName = type.toString();
        int beginIdx = typeName.indexOf('<'); int endIdx = typeName.lastIndexOf('>');
        if (beginIdx==-1 || endIdx == -1){
            if (Trigger.class.isAssignableFrom(clazz.getSuperclass().getSuperclass())){
                logger.debug("无法确定泛型信息:" + clazz.getName()+",尝试从父类加载");
                return getEventHandlerType((Class<? extends Trigger>) clazz.getSuperclass());
            }
            logger.error("无法确定泛型信息:" + clazz.getName());
            return null;
        }
        String handlerName = typeName.substring(beginIdx + 1, endIdx);
        try {
            Class handlerClazz = Class.forName(handlerName);
            if (EventHandler.class.isAssignableFrom(handlerClazz)) {
                return handlerClazz;
            }
        } catch (ClassNotFoundException e) {
            logger.error("无法加载类" + handlerName);
            return null;
        }
        return null;
    }

    static int getEventHandlerOrder(final Class<? extends EventHandler> handlerType){
        if (orderCache.containsKey(handlerType)) {
            return orderCache.get(handlerType);
        }
        if (handlerType.isAnnotationPresent(Priority.class)){
            Priority priority = handlerType.getAnnotation(Priority.class);
            orderCache.put(handlerType,priority.order());
            return priority.order();
        }else{
            orderCache.put(handlerType,Priority.NORMAL_PRIORITY);
            return Priority.NORMAL_PRIORITY;
        }
    }


}
